import Raphael from "raphael";
let paper = null;

/**
 * 初始化树节点和连线到dom 
 * 
 * {
 *      @param { String } containerId 容器ID
 *      @param { Graph } model 图形化容器实例
 *      @param { Array } nodes 带坐标的节点
 *      @param { Array } links 带坐标的连接线
 *      @param { String } connector 线条展示方式 当前仅支持 curve曲线  straight直线, 默认直线
 * } 
 * @returns { TTechnology }
 */
export const initDagreTree = ({ containerId="", model = null, nodes = [], links = [], connector = 'straight' }) => {
    const containerDom = document.querySelector(`#${containerId}`);
    const { clientWidth, clientHeight } = containerDom;

    // 创建SVG画布，每次都会新增到容器顶部
    paper = new Raphael(containerId, clientWidth, clientHeight)
    
    if (model) {
        // DagreJS图形的宽度和高度
        const graphWidth = model.graph().width;
        const graphHeight = model.graph().height;

        // 计算位移量
        const dx = (clientWidth - graphWidth) / 2;
        const dy = (clientHeight - graphHeight) / 2;

        // 设置viewBox保证内容完全展示
        const svg = paper.setViewBox(-dx, -dy, clientWidth, clientHeight)
    }

    renderView(nodes, links, connector)

    return paper
}

/**
 * 渲染节点和线
 * 
 * @param { Array } nodes 带坐标的节点
 * @param { Array } links 带坐标的连接线
 * @param { String } connector 线条展示方式 当前仅支持 curve曲线  straight直线, 默认直线
 */
export const renderView  = (nodes = [], links = [], connector="straight") => {
    if (!paper) return
    let i = 0
    while (i < nodes.length) {
        // const rect = paper.rect(nodes[i].x, nodes[i].y, nodes[i].width, nodes[i].height, 5)
        // Paint布局（例如SVG和HTML）通常使用标准的盒子模型，元素的x和y位置从左上角开始计算。
        // 然而，DagreJS对位置的计算则略有不同，其x和y是基于元素的中心点进行的。
        // 需要转换元素x和y坐标才能对齐连线
        const rect = paper.rect(nodes[i].x - nodes[i].width / 2, nodes[i].y - nodes[i].height / 2, nodes[i].width, nodes[i].height, 5);
        const rectBox = rect.getBBox()
        const { cx, cy, x:Rx, y:Ry, width, height }  = rectBox
        let textX = Rx + width / 2, textY = Ry + height / 2;
        const text = paper.text(textX, textY, nodes[i].label)
        text.attr('font-size', 18)
        text.attr('font-weight', '600')
        i++;
    }

    // 获取连接线数据
    const newLinks = linkConnector(connector, links)
    let j = 0;
    while (j < newLinks.length) {
        const path = paper.path(newLinks[j])
            path.attr('stroke', "#10ac84")
            path.attr('stroke-width', 3)
        j++;
    }
}

/**
 * 绘制线条模式
 * 当前仅支持 curve曲线  straight直线
 * 
 * @param { String } name 曲线名称 curve || straight
 * @param { Array } links 连接线集合
 */
export const linkConnector = (name = "straight", links = []) => {
    let newLineSet = []
    if (name == void 0) return links
    if (!Array.isArray(links)) {
        new Error('The connection line must be an array of objects')
    }
    if (links.length == 0) return []
    
    let i = 0;
    while (i < links.length) {
        const { points } = links[i];
        let _D = '';
        for(let k = 0; k < points.length; k++) {
            // straight 
            if (name === 'straight') {
                if (k === 0) {
                    _D += `M ${points[k].x} ${points[k].y} `
                } else {
                    _D += `L ${points[k].x} ${points[k].y} `
                }
            }
            // curve 
            if (name === 'curve') {
                if (k === 0) {
                    _D += `M ${points[k].x} ${points[k].y} `
                } else if (k === 1){
                    _D += `Q ${points[k].x} ${points[k].y} `
                } else {
                    _D += `${points[k].x} ${points[k].y}`
                }
            }  
        }
        newLineSet.push(_D)
        i++;
    }
    
    return newLineSet
}